home *** CD-ROM | disk | FTP | other *** search
- Path: newshost.cyberramp.net!news
- From: sinan@cyberramp.net (John Noland)
- Newsgroups: comp.lang.c
- Subject: Re: simple code, argc, argv, strcmp()
- Date: 21 Feb 1996 00:01:41 GMT
- Organization: Prose Software
- Message-ID: <4gdnd5$489@newshost.cyberramp.net>
- References: <11f7cc$17261a.3b3@daprez> <9602011151.AA04526@dxmint.cern.ch> <4g040v$7jj@maverick.tad.eds.com>
- NNTP-Posting-Host: ramp2-16.cyberramp.net
- X-Newsreader: WinVN 0.99.5
-
- In article <4g040v$7jj@maverick.tad.eds.com>, gulleha@vaxixhp3.vaxix.slg.eds.com says...
-
- >>int main (int argc, char **argv) {
- >>
- >> if (!strcmp(argv[1],"-d") || !strcmp(argv[1],"-e")) {
- >> Usage();
- >> }
- >...
- >>
- >>Can someone see what's wrong with this ?
- >>am I not using strcmp() right ?
- >
-
- I need to make the following statements just to be thorough:
-
- 1. int strcmp(const char *s1, const char *s2);
- strcmp returns a value that is
- < 0 if s1 is less than s2
- == 0 if s1 is the same as s2
- > 0 if s1 is greater than s2
-
- 2. if (conditional-expression) TRUE-STATEMENT <else FALSE-STATEMENT>
- The conditional-expression must be of scalar type. The expression is
- evaluated. If the value is zero, we say that the conditional-expression
- is FALSE; otherwise, it is TRUE.
- If there is no else clause, and the conditional-expression is TRUE,
- TRUE-STATEMENT is executed; otherwise, TRUE-STATEMENT is ignored.
-
- 3. In the expression E1 || E2, both operands must be of scalar type. The
- result is of type int, and the result is 1 (TRUE) if either of the values
- of E1 or E2 are nonzero. Otherwise, the result is 0 (FALSE).
- E1 is evaluated first; if E1 is nonzero, E1 || E2 gives 1 (TRUE), and E2
- is not evaluated. This so-called "short-circuit evaluation" is true in
- Microsoft and Borland compilers, but is not specified by "K&R" or
- ANSI. Your compiler may or may not do it this way.
-
- 4. The unary negation operator ! converts a non-zero (TRUE) operand into
- zero, and a zero (FALSE) operand into 1.
-
- 5. You will need to check the language reference that came with your
- compiler to verify precedence and order of evaluation. They tend to
- be consistent from one to another, but they aren't specified in any
- official standard, so yours could be different(BLECHHH!).
-
- How does the statement evaluate:
-
- if argv[1] is neither "-d" or "-e"?
-
- 1. strcmp returns an int not equal to zero for each expression.
- 2. The ! operator logically negates the return value of each
- strcmp, giving zero for both. Our statement is now essentially:
- <if (0 || 0)>.
- 3. 0 || 0 gives 0. We now have <if (0)> or <if (FALSE)>
-
- RESULT: usage() is not called. This is an INCORRECT result!
-
- if argv[1] is "-d" or "-e"?
-
- 1. One strcmp returns zero, the other returns non-zero.
- 2. The ! operator logically negates the return value of
- each strcmp, giving zero for one and one for the other.
- Our statement is now essentially: <if (1 || 0)> or
- <if (0 || 1)>.
- 3. 1 || 0 or 0 || 1 gives 1. We now have <if (1)>.
-
- RESULT: usage() is called. This is an incorrect result!
-
- if argv[1] is equal to "-d" and "-e"?
-
- Wait a minute! Is this combination possible? Do you see the problem
- with this? The same variable cannot possibly have two different
- values at the same time.
-
- To ease the illustration of this and rid strcmp from the discussion,
- let's use an int in simplified conditional statements. Your statement
- above would look something like this (though not exactly, I'll get to
- that in a minute!):
-
- int number;
- ...
- if ((number != 6) || (number != 9)) some_function();
-
-
- This a common mistake in most programming languages (not just C). The
- problem is that at least one of the simple conditions will always be
- true; number will always either not contain a 6 or not contain a 9, or
- not contain either one. Thus, the compound condition is always true.
- This isn't true with the strcmp example above. Why is that, do you
- reckon? Here's a hint, I think you can figure it out yourself:
- if (!(number == 6) || !(number == 9)) some_function();
-
- The "moral" of all of this is a lesson in boolean algebra, which is:
- When negating conditions separated by ||: if !(exp1 || exp2), the
- stated conditions become: if (!exp1 AND !exp2)...
-
- Hence,
- if !(strcmp(argv[1], "-d") || strcmp(argv[1], "-e") usage();
- or
- if (!strcmp(argv[1], "-d") && !strcmp(argv[1], "-e") usage();
-
- would be solutions that do what you desire.
-
- Sorry this is such a long answer, but I've found that only the real
- gurus are allowed to be terse in this group.
-
- -John
-
-